import numpy as np

def differential_evolution(func, mode="min", D=2, N=50, F=0.5, CR=0.7, G=100, bounds=None, seed=None):
    """
    差分进化算法
    
    参数:
    func: 目标函数
    mode: "min" 表示最小化, "max" 表示最大化
    D: 问题的维度
    N: 种群中的个体数量
    F: 差分权重
    CR: 交叉概率
    G: 迭代代数
    bounds: 搜索边界 [(min1, max1), (min2, max2), ...] 或 (min, max) 应用于所有维度
    seed: 随机数种子
    
    返回:
    best_solution: 最优解
    best_fitness: 最优适应度值
    population: 最终种群
    """
    if seed is not None:
        np.random.seed(seed)
    
    # 初始化种群
    if bounds is None:
        # 默认在[0,1]范围内初始化
        population = np.random.rand(N, D)
    else:
        if isinstance(bounds[0], (int, float)):
            # 如果bounds是(min, max)形式，应用于所有维度
            bounds = [bounds] * D
        
        population = np.zeros((N, D))
        # 每个维度的 bound 约束
        for i in range(D):
            low, high = bounds[i]
            population[:, i] = np.random.uniform(low, high, N)
    
    # 适应度函数（根据最小化或最大化调整）
    def fitness_func(x):
        if mode == "min":
            return func(x)
        elif mode == "max":
            return -func(x)  # 最大化问题转换为最小化
        else:
            raise ValueError("mode must be 'min' or 'max'")
    
    # 主循环
    for generation in range(G):
        for i in range(N):
            # 变异
            idxs = [idx for idx in range(N) if idx != i]
            r1, r2, r3 = population[np.random.choice(idxs, 3, replace=False)]
            mutant_vector = r1 + F * (r2 - r3)
            
            # 边界处理
            if bounds is not None:
                for j in range(D):
                    # bounds 是 list 形式还是 tuple 形式
                    low, high = bounds[j] if isinstance(bounds[0], (list, tuple)) else bounds
                    # 裁剪到边界范围内
                    mutant_vector[j] = np.clip(mutant_vector[j], low, high)
            
            # 对每个维度 交叉
            trial_vector = np.array([
                mutant_vector[j] if np.random.rand() < CR or j == np.random.randint(D) 
                else population[i, j] for j in range(D)
            ])
            
            # 选择
            if fitness_func(trial_vector) < fitness_func(population[i]):
                population[i] = trial_vector
    
    # 找到最优解
    fitness_values = [fitness_func(individual) for individual in population]
    best_idx = np.argmin(fitness_values)
    best_solution = population[best_idx]
    best_fitness = func(best_solution)  # 返回原始函数值
    
    return best_solution, best_fitness, population


if __name__ == "__main__":
    # 目标函数示例
    def objective_function(x):
        return x[0]**2 + x[1]**2

    # 测试最小化
    print("最小化测试:")
    best_sol, best_fit, final_pop = differential_evolution(
        func=objective_function, 
        mode="min", 
        D=2, 
        N=50, 
        F=0.5, 
        CR=0.7, 
        G=1000, 
        bounds=(-10, 10),
        seed=42
    )
    print(f"最优解: {best_sol}")
    print(f"最优值: {best_fit}")

    print("\n最大化测试:")
    # 测试最大化（寻找函数的最大值点）
    def test_max_function(x):
        return -(x[0]-2)**2 - (x[1]-3)**2 + 10  # 最大值在(2,3)处，值为10

    best_sol_max, best_fit_max, final_pop_max = differential_evolution(
        func=test_max_function, 
        mode="max", 
        D=2, 
        N=50, 
        F=0.5, 
        CR=0.7, 
        G=1000, 
        bounds=[(-10, 10)] * 50, # 或者 (-10, 10)
        seed=42
    )
    print(f"最优解: {best_sol_max}")
    print(f"最优值: {best_fit_max}")